package com.dgut.forum.services.impl;

import com.dgut.forum.common.AppResult;
import com.dgut.forum.common.ResultCode;
import com.dgut.forum.dao.UserMapper;
import com.dgut.forum.exception.ApplicationException;
import com.dgut.forum.model.User;
import com.dgut.forum.services.IUserService;
import com.dgut.forum.utils.MD5Util;
import com.dgut.forum.utils.StringUtil;
import com.dgut.forum.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

@Slf4j
@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    private UserMapper userMapper;
    @Override
    public void createNormalUser(User user) {
        //检查传过来的用户参数是否为空
        if(user==null){
            log.info("user为空,"+ ResultCode.ERROR_IS_NULL);
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        //数据库中找是否存在该用户,用户名唯一
        User existsUser= userMapper.selectByUserName(user.getUsername());
        //如果用户存在
        if(existsUser!=null){
            log.info(ResultCode.FAILED_USER_EXISTS+"username="+user.getUsername());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
        }

        //除了必须传递的参数外,其他参数要设置默认值
        user.setGender((byte) 2);
        user.setArticleCount(0);
        user.setIsAdmin((byte) 0);
        user.setState((byte) 0);
        user.setDeleteState((byte) 0);
        Date date=new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);

        int ret=userMapper.insertSelective(user);
        if(ret!=1){
            log.info("新增用户失败"+ResultCode.FAILED_CREATE);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
        log.info(ResultCode.SUCCESS+" 新增用户成功,username="+user.getUsername());
    }

    @Override
    public User selectByUserName(String username) {
        if(StringUtil.stringNoLength(username)){
            log.info("username为空");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user=userMapper.selectByUserName(username);
        if(user==null){
            log.info("用户不存在,username="+username);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        return user;
    }

    @Override
    public User login(String username, String password) {
        //校验参数
        if(StringUtil.stringNoLength(username)||StringUtil.stringNoLength(password)){
            log.info("username或者password为空");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //根据用户名去数据库查找用户
        User user=userMapper.selectByUserName(username);
        if(user==null){
            log.info("用户不存在,username="+username);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //校验密码
        String salt=user.getSalt();
        String encrypt=MD5Util.md5Second(password,salt);

        if(!encrypt.equals(user.getPassword())){
            log.info("用户="+username+"登录时,输入的密码错误");
            throw  new ApplicationException(AppResult.failed(ResultCode.FAILED_NOLOGIN));
        }

        //用户名正确,密码正确
        return user;
    }

    @Override
    public User selectByPrimaryKey(Long id) {
        if(id==null){
            log.info("id为空");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user=userMapper.selectByPrimaryKey(id);
        if(user==null){
            log.info("用户不存在,id="+id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        return user;
    }
    /*
    * 新增文章时在文章新增之后修改用户的文章数量
    *
    * */
    @Override
    public void addOneToUserArticleCount(Long id) {
        if(id==null||id<0){
            log.warn("新增用户文章数量失败,id="+id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ADD_COUNT));
        }
        User user=userMapper.selectByPrimaryKey(id);
        if(user==null){
            log.info("新增板块文章数量时查不到用户信息,user id="+id);
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        User updateUser=new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount()+1);
        int ret=userMapper.updateByPrimaryKeySelective(updateUser);
        if(ret!=1){
            log.error("新增用户文章数量失败,user id="+id+" ,"+ResultCode.ERROR_SERVICES.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }

        log.info("新增用户 user id="+id+"文章数量成功");
    }

    @Override
    public void subOneToUserArticleCount(Long id) {
        if(id==null||id<0){
            log.warn("用户id错误,id="+id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User user=userMapper.selectByPrimaryKey(id);
        if(user==null){
            log.info("减少板块文章数量时,查不到用户信息,user id="+id);
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        User updateUser=new User();
        updateUser.setId(user.getId());
        updateUser.setArticleCount(user.getArticleCount()-1);
        if(updateUser.getArticleCount()<0){
            updateUser.setArticleCount(0);
        }
        int ret=userMapper.updateByPrimaryKeySelective(updateUser);
        if(ret!=1){
            log.error("减少用户文章数量时,服务器发生失败,user id="+id);
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }

        log.info("减少用户 user id="+id+",文章数量成功");
    }

    @Override
    public void updateUserInfo(User user) {

        if(user==null||user.getId()==null||user.getId()<=0){
            log.info("修改用户信息参数校验失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        User existUser=userMapper.selectByPrimaryKey(user.getId());
        if(existUser==null){
            log.info("要修改的用户不存在");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //新建一个对象用来修改符合修改条件的
        //避免闯入的对象乱修改
        User updateUser=new User();
        //检验是否需要修改,最后检验如果还是false,就是不需要修改
        boolean check=false;
        //根据用户Id.所以必须有用户Id
        if(user.getId()!=null&&existUser.getId().equals(user.getId())){
            updateUser.setId(user.getId());
        }
        //如果需要修改用户名,也要检验用户是否合法
        if(user.getUsername()!=null&&!existUser.getUsername().equals(user.getUsername())){
            //因为修改用户名是唯一的,所以要检验是否因为存在
            User checkUser=userMapper.selectByUserName(user.getUsername());
            if(checkUser!=null){
                log.info("要修改用户名已经存在");
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
            }
            updateUser.setUsername(user.getUsername());
            check=true;
        }

        //如果需要修改用户昵称,也要检验是否合法
        //如果要修改的信息中用户昵称不为空就要修改,其中只要符合已经存在的用户的昵称为空或者两者的昵称不相同就可以修改
        if(user.getNickname()!=null&&(existUser.getNickname()==null||!existUser.getNickname().equals(user.getNickname()))){
            updateUser.setNickname(user.getNickname());
            check=true;
        }

        //如果需要修改用户电话号码,也要检验是否合法
        //如果要修改的信息中用户电话号码不为空就要修改,其中只要符合已经存在的用户的电话号码为空或者两者的电话号码不相同就可以修改
        if(user.getPhoneNum()!=null&&(existUser.getPhoneNum()==null||!existUser.getPhoneNum().equals(user.getPhoneNum()))){
            updateUser.setPhoneNum((user.getPhoneNum()));
            check=true;
        }

        //如果需要修改用户邮箱,也要检验是否合法
        //如果要修改的信息中用户邮箱不为空就要修改,其中只要符合已经存在的用户的邮箱为空或者两者的邮箱不相同就可以修改
        if(user.getEmail()!=null&&(existUser.getEmail()==null||!existUser.getEmail().equals(user.getEmail()))){
            updateUser.setEmail((user.getEmail()));
            check=true;
        }

        //如果需要修改用户性别,也要检验是否合法
        //如果要修改的信息中用户性别不为空就要修改,其中只要符合已经存在的用户的性别或者两者的性别不相同就可以修改
        if(user.getGender()!=null&&(existUser.getGender()==null||!existUser.getGender().equals(user.getGender()))){
            if(user.getGender()<0||user.getGender()>2){
                user.setGender((byte) 2);
            }
            updateUser.setGender((user.getGender()));
            check=true;
        }

        //如果需要修改用户头像,也要检验是否合法
        //如果要修改的信息中用户头像不为空就要修改,其中只要符合已经存在的用户的头像为空或者两者的头像不相同就可以修改
        if(user.getAvatarUrl()!=null&&(existUser.getAvatarUrl()==null||!existUser.getAvatarUrl().equals(user.getAvatarUrl()))){
            updateUser.setAvatarUrl((user.getAvatarUrl()));
            check=true;
        }

        //如果需要修改用户个人介绍,也要检验是否合法
        //如果要修改的信息中用户个人介绍不为空就要修改,其中只要符合已经存在的用户的个人介绍为空或者两者的个人介绍不相同就可以修改
        if(user.getRemark()!=null&&(existUser.getRemark()==null||!existUser.getRemark().equals(user.getRemark()))){
            updateUser.setRemark((user.getRemark()));
            check=true;
        }

        //检验是否需要提交修改
        if(check){
            int row=userMapper.updateByPrimaryKeySelective(updateUser);
            if(row!=1){
                log.error("修改用户信息,出现服务器错误");
                throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
            }
            log.info("修改用户信息成功");
        }else{
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
    }


    @Override
    public void modifyPassword(Long id,String oldPassword, String newPassword) {
        //校验参数
        if(id==null||id<=0||StringUtil.isEmpty(oldPassword)||StringUtil.isEmpty(newPassword)){
            log.info("修改密码,参数校验失败");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
        //校验用户状态
        User user=userMapper.selectByPrimaryKey(id);
        if(user==null||user.getDeleteState()==1){
            log.info("修改密码,指定用户不存在");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
        //校验老密码是否正确;
        String checkPassword=MD5Util.md5Second(oldPassword,user.getSalt());
        if(!checkPassword.equals(user.getPassword())){
            log.info("修改密码,输入旧密码错误");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_OLD_PASSWORD_ERROR));
        }
        //判断新旧密码是否相同,相同就不要修改
        if(oldPassword.equals(newPassword)){
            log.info("新旧密码相同,不需要修改");
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_TWO_PWD_SAME));
        }
        //创建一个新的对象,通过动态修改用户密码,只保留需要修改的字段
        String newSalt= UUIDUtil.UUID_32();
        newPassword=MD5Util.md5Second(newPassword,newSalt);
        User updateUser=new User();
        updateUser.setId(user.getId());
        updateUser.setPassword(newPassword);
        updateUser.setSalt(newSalt);

        int row=userMapper.updateByPrimaryKeySelective(updateUser);
        if(row!=1){
            log.error("修改用户密码,出现服务器错误");
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_SERVICES));
        }
        log.info("修改用户密码成功");
    }
}
